package com

import android.annotation.TargetApi
import android.app.ActivityManager
import android.app.Application
import android.app.IntentService
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Debug
import android.os.Process
import android.text.format.Formatter
import com.andova.ext.v

class WorkApplication : Application() {
    override fun onCreate() {
        super.onCreate()
//        XCrash.init(this, CrashHandler(this))
        startService(Intent(this, ApplicationService::class.java))
    }
}

class ApplicationService : IntentService("appservice") {
    override fun onHandleIntent(intent: Intent?) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
        while (true) {
            memoryProfiler()
            Thread.sleep(5000L)
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private fun memoryProfiler(): Float {
        val am = getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
        am ?: return -1f
        return try {
            // 统计进程的内存信息 totalPss
            val memInfo: Array<Debug.MemoryInfo> = am.getProcessMemoryInfo(intArrayOf(Process.myPid()))
            if (memInfo.isNullOrEmpty()) -1f
            /**
             * 读取内存信息,跟Android Profiler 分析一致
             */
            val javaMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.java-heap")) * 1024 // convert to bytes
            val nativeMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.native-heap")) * 1024 // convert to bytes
            val graphicsMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.graphics")) * 1024 // convert to bytes
            val stackMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.stack")) * 1024 // convert to bytes
            val codeMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.code")) * 1024 // convert to bytes
            val othersMemL: Long = convertToLong(memInfo[0].getMemoryStat("summary.system")) * 1024 // convert to bytes
            val javaMemS: String = Formatter.formatFileSize(this, javaMemL)
            val nativeMemS: String = Formatter.formatFileSize(this, nativeMemL)
            val graphicsMemS: String = Formatter.formatFileSize(this, graphicsMemL)
            val stackMemS: String = Formatter.formatFileSize(this, stackMemL)
            val codeMemS: String = Formatter.formatFileSize(this, codeMemL)
            val othersMemS: String = Formatter.formatFileSize(this, othersMemL)
            val dalvikPss = Formatter.formatFileSize(this, javaMemL + nativeMemL + graphicsMemL + stackMemL + codeMemL + othersMemL)
            v("mem profiler -> { javaMem:$javaMemS, nativeMem:$nativeMemS, graphicsMem:$graphicsMemS, stackMem:$stackMemS, codeMem:$codeMemS, otherMem:$othersMemS, totalMem:$dalvikPss }")
            dalvikPss.toFloat()
        } catch (e: Exception) {
            -1f
        }
    }

    private fun convertToLong(value: Any?, defaultValue: Long = 0L): Long {
        return if (value == null || "" == value.toString().trim { it <= ' ' }) {
            defaultValue
        } else try {
            value.toString().toLong()
        } catch (e: Exception) {
            try {
                java.lang.Double.valueOf(value.toString()).toLong()
            } catch (e2: java.lang.Exception) {
                defaultValue
            }
        }
    }
}